package com.salinity.kun.task;

import java.io.BufferedReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.salinity.kun.algorithm.harmonic.TideSymbol;
import com.salinity.kun.helper.ConstantHelper;
import com.salinity.kun.helper.HarmonicHelper;
import com.salinity.kun.util.DateUtil;

/**
 * 白茆站点预测
 * 
 * @author Administrator
 *
 */
public class BaimaoPredictionTask implements ITask {

//	public void predictTide1(double[] s0, TideSymbol[] tidesSymbol, double[][] A, double[][] B, double k)
//			throws ParseException {
//
//		HarmonicHelper harmonicHelper = new HarmonicHelper();
//
//		double ht, Ht, t, dt = 5 / 60f;
//		double sm, sk, am, ak, bm, bk, sigma, tempA, tempB, tempS;
//		double[] Q = {69680
//
// };
//		TideSymbol tempTS;
//		SimpleDateFormat sdf = ConstantHelper.getDateFormat();
//
//		Date sDate = sdf.parse("2017/1/1 0:0:0");
//		Date preDate = sdf.parse("2017/7/5 9:40");
//
////		double S0 = 1.9653;
////
////		double[] a = { 1.9653, -0.2115, -0.217, -0.2217, -0.1336, -0.0226, -0.0912, -0.0069, 0.1197, -0.1051, -0.0795,
////				-0.0189 };
////		double[] b = { 0.379, 0.0932, 0.1561, 0.1374, -0.1218, 0.0411, -0.1253, -0.0473, 0.0167, 0.0095, 0.0394 };
//
//		Calendar calendar = DateUtil.Date2Calendar(preDate);
//		double oneDay;
//		sm = s0[1];
//		sk = s0[2];
//
//		for (int i = 0; i < Q.length; i++) {
//			t = (calendar.getTime().getTime() - sDate.getTime()) / (1000 * 60 * 60f);
//			oneDay = 0;
//			tempS = getfvalue(sm, sk, Q[i]);
//			while (oneDay < 24) {
//				ht = 0.0;
//				ht += s0[0] - tempS;
//				for (int j = 0; j < tidesSymbol.length; j++) {
//					tempTS = tidesSymbol[j];
//					am = A[j][1];
//					ak = A[j][2];
//					bm = B[j][1];
//					bk = B[j][2];
//
//					tempA = getfvalue(am, ak, Q[i]);
//					tempB = getfvalue(bm, bk, Q[i]);
//					sigma = harmonicHelper.getAngularVelocity(tempTS);
//					ht += (A[j][0] - tempA) * Math.cos(sigma * t) + (B[j][0] - tempB) * Math.sin(sigma * t);
//				}
//				System.out.println(ht * k);
//				t += dt;
//				oneDay += dt;
//				calendar.add(Calendar.MINUTE, (int) (dt * 60));
//
//			}
//			// System.out.println();
//			// System.out.println(sdf.format(calendar.getTime()));
//
//		}
//
//	}

	public void predictTide(double[] s0, TideSymbol[] tidesSymbol, double[][] A, double[][] B, double k)
			throws ParseException {

		HarmonicHelper harmonicHelper = new HarmonicHelper();

		double ht, Ht, t, dt = 5 / 60f;
		double sm, sk, am, ak, bm, bk, sigma, tempA, tempB, tempS;
//		 double[] Q = {
//		 22400,
//		 22600,
//		 22400
//		 };
		 
//		 double[] Q = {
//				 12600,
//				 12300,
//				 12200
//
//				 };
		
		double[] Q = {
				 31800,
				 32200,
				 32600,
			 	33500
				 };
		
		
		
//		 double[] Q = {
//				 29800,
//				 29900,
//				 29800
//		 };
		
		
//		 double[] Q = {
//				 67900,
//				 67500,
//				 66600,
//				 65600
//
//		 };
		TideSymbol tempTS;
		SimpleDateFormat sdf = ConstantHelper.getDateFormat();
		Date sDate = sdf.parse("2017/1/1 0:0:0");

		 // Date preDate = sdf.parse("2018/3/25 2:15:00");
		//	Date preDate = sdf.parse("2017/12/26 15:20");
		
		Date preDate = sdf.parse("2017/10/5 5:20");
		
		//Date preDate = sdf.parse("2017/9/21 00:00:00");
		
		//	Date preDate = sdf.parse("2017/7/10 19:40");
		

		// double S0 = 1.9653;
		//
		// double[] a = { 1.9653, -0.2115, -0.217, -0.2217, -0.1336, -0.0226, -0.0912,
		// -0.0069, 0.1197, -0.1051, -0.0795,
		// -0.0189 };
		// double[] b = { 0.379, 0.0932, 0.1561, 0.1374, -0.1218, 0.0411, -0.1253,
		// -0.0473, 0.0167, 0.0095, 0.0394 };

		Calendar calendar = DateUtil.Date2Calendar(preDate);
		double oneDay;
		sm = s0[1];
		sk = s0[2];

		for (int i = 0; i < Q.length; i++) {
			t = (calendar.getTime().getTime() - sDate.getTime()) / (1000 * 60 * 60f);
			oneDay = calendar.get(Calendar.HOUR_OF_DAY) + calendar.get(Calendar.MINUTE) / 60f;
			tempS = s0[0] - getfvalue(sm, sk, Q[i]);
			while (oneDay < 24) {
				ht = 0.0;
				ht += tempS;

				for (int j = 0; j < tidesSymbol.length; j++) {
					tempTS = tidesSymbol[j];
					am = A[j][0];
					ak = A[j][1];
					bm = B[j][0];
					bk = B[j][1];

					tempA =getfvalue(am, ak, Q[i]);
					tempB =getfvalue(bm, bk, Q[i]);
					//System.out.println(tempA+","+tempB);
					sigma = harmonicHelper.getAngularVelocity(tempTS);
					ht += tempA * Math.cos(sigma * t) + tempB * Math.sin(sigma * t);

				}
				// System.out.println(ht * k);
				System.out.println(ht);
				t += dt;
				oneDay += dt;
				calendar.add(Calendar.MINUTE, (int) (dt * 60));
			}
			// System.out.println();
			// System.out.println(sdf.format(calendar.getTime()));
		}
	}

	/**
	 * 衰减值的求取
	 * 
	 * @param m
	 * @param k
	 * @param Q
	 * @return
	 */
	public double getfvalue(double m, double k, double Q) {
		return m * Math.exp(-k * Q);
	}

	public void getDataFromFile(Path filePath, double[][] s, double[][] a, double[][] b) throws IOException {

		try (BufferedReader br = Files.newBufferedReader(filePath)) {
			String line = null;
			String[] strArr;
			List<double[]> dataList = new ArrayList<>();
			double[] tempData;
			int i = 0;
			while ((line = br.readLine()) != null) {
				strArr = line.trim().split(",");
				if (strArr.length == 3) {
					tempData = new double[3];
					for (i = 0; i < 3; i++) {
						tempData[i] = Double.parseDouble(strArr[i]);
					}
					dataList.add(tempData);
				}else if(strArr.length == 2) {
					tempData = new double[2];
					for (i = 0; i < 2; i++) {
						tempData[i] = Double.parseDouble(strArr[i]);
					}
					dataList.add(tempData);
				}
			}
			
			int len = (dataList.size()-1)/2;
			
			s[0] = dataList.get(0);
			for (i = 0; i < len; i++) {
				a[i] = dataList.get(i + 1);
				b[i] = dataList.get(i + len+1);
			}

		}

	}

	@Override
	public boolean run() throws IOException, ParseException {
		Map<TideSymbol, double[]> dataMap = new HashMap<>();

		TideSymbol[] tidesSymbol = { TideSymbol.M2, 
				TideSymbol.S2, 
//				TideSymbol.N2,
//				TideSymbol.K2,
				
				TideSymbol.K1,
				TideSymbol.O1, 
//		    	TideSymbol.P1, 
//				TideSymbol.Q1,
				
				TideSymbol.M4,
				TideSymbol.M6, 
				TideSymbol.MS4 };
		double k = 1.024125;

		double s[][] = new double[1][3];
		double a[][] = new double[tidesSymbol.length][2];
		double b[][] = new double[tidesSymbol.length][2];
//		 Path inputPath =
//		 Paths.get("E:\\Kuner\\BYLW\\Jworkspace\\saltyCode\\testify\\data\\ABS_Q.csv");
		Path inputPath =
				 Paths.get("E:\\Kuner\\BYLW\\Jworkspace\\saltyCode\\testify\\data\\ABS_Q_7.csv");
//			Path inputPath =
//					 Paths.get("E:\\Kuner\\BYLW\\Jworkspace\\saltyCode\\testify\\data\\ABS_Q_11=1.csv");
		//Path inputPath = Paths.get("E:\\Kuner\\BYLW\\Jworkspace\\saltyCode\\testify\\data\\ABS_Q_no.csv");
		getDataFromFile(inputPath, s, a, b);
		predictTide(s[0], tidesSymbol, a, b, k);

		return false;
	}

	public static void main(String[] args) throws IOException, ParseException {
		ITask task = new BaimaoPredictionTask();
		task.run();
	}

}
